#ifndef CALENDARVIEW_H
#define CALENDARVIEW_H

#include <QTableView>
#include <QItemDelegate>
#include <QPushButton>
#include <QLayout>
#include <QWidget>
#include <QLabel>
//#include <QTimer>
#include "CalendarModel.h"

class EventSelector
{
public:
    EventSelector()
        : selectNumber(-1),
          firstVisible(1),
          maxVisible(5),
          selectDate(QDate()),
          width(0)
    {
    }

    int selectNumber;
    int firstVisible;
    int maxVisible;
    QDate selectDate;
    EventList_t selectList;
    int width;
    QModelIndex index;
};

struct Zone
{
    enum ZoneType
    {
        EventHeader,
        EventImageHeader,
        EventImage,
        EventImageBorder,
        EventTail,
        Particle,
        Footer,
        FooterIcon
    };
    bool visible;
    QRect rect;
    ZoneType type;
    Event event;
    int order;
};

class EventListView
{
public:
    EventListView(const EventList_t &list, const QRect &rect);

    QList<Zone> calcZones(const EventSelector &selector, const QDate &date) const;
    void paint(QPainter *painter, const EventSelector &selector, const QDate &date) const;
    void mousePressEvent(QMouseEvent *event, EventSelector &selector, const QDate &date);
    bool mouseWheelEvent(QWheelEvent *event, EventSelector &selector, const QDate &date);

private:
//    void paintEvent(QPainter *painter, const Event &currentEvent, const QRect &rect, int eventHeight) const;
//    void paintEventHeader(QPainter *painter, const int order, const Event &event,
//                          const QRect &rect, int eventHeight) const;
    void paintEventIcon(QPainter *painter, const QString &iconPath, const QPoint &point) const;
//    void paintEventFooterSelector(QPainter *painter, const EventList_t &eventList,
//                                  const Event &currentEvent, const QRect &rect, int eventHeight) const;

    EventList_t m_list;
    QRect m_rect;
    QList<QRect> m_headers;
};

class CalendarDelegate : public QItemDelegate
{
    Q_OBJECT
public:
    explicit CalendarDelegate(QObject *parent = 0);

    virtual void paint(QPainter *painter, const QStyleOptionViewItem &option,
                       const QModelIndex &index) const;
    virtual QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
                                  const QModelIndex &index) const;
    virtual bool editorEvent(QEvent *event, QAbstractItemModel *model,
                             const QStyleOptionViewItem &option,
                             const QModelIndex &index);

//    virtual void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option,
//                                      const QModelIndex &index) const;

private:
    void paintDate(QPainter *painter, const QStyleOptionViewItem &option,
                   const QDate &date, bool isWeekend, bool isDayOfAnotherMonth) const;
    void paintCurrent(QPainter *painter, const QStyleOptionViewItem &option, const QDate &date) const;
    void paintCursor(QPainter *painter, const QStyleOptionViewItem &option) const;

    void paintCounter(QPainter *painter, const QStyleOptionViewItem &option) const;

    void paintWeather(QPainter *painter, const QStyleOptionViewItem &option) const;

    void paintWeekNumber(QPainter *painter, const QStyleOptionViewItem &option, int week) const;
    void paintDayOfWeek(QPainter *painter, const QStyleOptionViewItem &option,
                        const QString &dayOfWeek, bool isWeekend) const;
    void paintHeader(QPainter *painter, const QStyleOptionViewItem &option) const;

    QFont headerFont(int cellHeight) const;
    QFont dateFont(int cellHeight) const;
    QFont counterFont(int cellHeight) const;
    QFont dayTempFont(int cellHeight) const;
    QFont nightTempFont(int cellHeight) const;

//    mutable QRect selectRect; // TODO as VisualRect
    EventSelector m_selector;
    QWidget *widget;
//    QTimer timer;
    QMap <QDate, QLabel *> widgetList;

public slots:
    void runEvent(QEvent *event, const QModelIndex &index, const QRect &rect, bool &needUpdate);
    void updateData(const QModelIndex &topLeft, const QModelIndex &bottomRight);
};

class CalendarView : public QTableView
{
    Q_OBJECT
public:
    explicit CalendarView(QWidget *parent = 0);

    void internalUpdate() { updateGeometries(); }
    virtual void keyboardSearch(const QString &search) { Q_UNUSED(search) }
    virtual void setModel(QAbstractItemModel *model);
//    void update();

protected:
    void changeSelection(const QDate &date, bool updateModel);
    void changeSelection(const QModelIndex &index);

    QModelIndex moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers);

    void mousePressEvent(QMouseEvent *event);
    void wheelEvent(QWheelEvent *event);
    void showEvent(QShowEvent *event);

//    QDate handleMouseEvent(const QPoint &pos);
//    void mouseDoubleClickEvent(QMouseEvent *event);
//    void mouseMoveEvent(QMouseEvent *event);
//    void mouseReleaseEvent(QMouseEvent *event);

//    void keyPressEvent(QKeyEvent *event);
//    bool event(QEvent *event);

private:
//    bool validDateClicked;
    CalendarDelegate *m_delegate;

//signals:
//    void showDate(const QDate &date);
//    void changeDate(const QDate &date, bool changeMonth);
//    void clicked(const QDate &date);
//    void editingFinished();

public slots:

signals:
    void sendEvent(QEvent *event, const QModelIndex &index, const QRect &rect, bool &needUpdate);
};

#endif // CALENDARVIEW_H
